﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace WHLRDF
{
    /// <summary>
    /// 加密解密
    /// </summary>
    public class MD5Helper
    {
       /// <summary>
       /// md5加密
       /// </summary>
       /// <param name="normalTxt"></param>
       /// <param name="_input_charset"></param>
       /// <returns></returns>
        public static string MD5Encrypt(string normalTxt, string _input_charset= "UTF-8")
        {
            byte[] buffer = new MD5CryptoServiceProvider().ComputeHash(Encoding.GetEncoding(_input_charset).GetBytes(normalTxt));
            StringBuilder builder = new StringBuilder(0x20);
            for (int i = 0; i < buffer.Length; i++)
            {
                builder.Append(buffer[i].ToString("x").PadLeft(2, '0'));
            }
            return builder.ToString();
        }
        /// <summary>
        /// 获取系统签名
        /// </summary>
        /// <param name="normalTxt"></param>
        /// <returns></returns>
        public static string GetToken(string normalTxt)
        {
            return MD5Encrypt(normalTxt + ApplicationEnvironments.Site.MD5key).ToLower();
        }
        /// <summary>
        /// 获取系统签名
        /// </summary>
        /// <param name="normalTxt"></param>
        /// <returns></returns>
        public static string GetToken(SortedDictionary<string, string> dicParam)
        {
            var content = CreateSortString(dicParam);
            return MD5Encrypt(content + ApplicationEnvironments.Site.MD5key).ToLower();
        }

        public static string CreateSortString(SortedDictionary<string, string> dicArray)
        {
            var sPara = ParamFilter(dicArray);

            return CreateLinkString(sPara);
        }
        /// <summary>
        /// 除去数组中的空值和签名参数并以字母a到z的顺序排序
        /// </summary>
        /// <param name="dicArrayPre">过滤前的参数组</param>
        /// <returns>过滤后的参数组</returns>
        public static Dictionary<string, string> ParamFilter(SortedDictionary<string, string> dicArrayPre)
        {
            Dictionary<string, string> dicArray = new Dictionary<string, string>();
            foreach (KeyValuePair<string, string> temp in dicArrayPre)
            {
                if (temp.Key.ToLower() != "sign" && temp.Key.ToLower() != "sign_type" && temp.Value != "")
                {
                    dicArray.Add(temp.Key.ToLower(), temp.Value);
                }
            }

            return dicArray;
        }

        /// <summary>
        /// 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        /// </summary>
        /// <param name="sArray">需要拼接的数组</param>
        /// <returns>拼接完成以后的字符串</returns>
        public static string CreateLinkString(Dictionary<string, string> dicArray)
        {
            StringBuilder prestr = new StringBuilder();
            int index = 0;
            foreach (KeyValuePair<string, string> temp in dicArray)
            {
                if (!string.IsNullOrEmpty(temp.Value))
                {
                    if (index > 0)
                    {
                        prestr.Append("&");
                    }
                    index++;
                    prestr.Append(temp.Key + "=" + temp.Value);
                }


            }

            return prestr.ToString();
        }

        #region  RSA
        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="normaltxt"></param>
        /// <returns></returns>
        public static string RSAEncrypt(string normaltxt)
        {
            var bytes = Encoding.ASCII.GetBytes(normaltxt);
            var rsa = new RSACryptoServiceProvider(new CspParameters { KeyContainerName = "ccccccccccc" });


            var encryptBytes = rsa.Encrypt(bytes, false);
            return Convert.ToBase64String(encryptBytes);
        }
        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="normaltxt"></param>
        /// <returns></returns>
        public static string RSADecrypt(string securityTxt)
        {
            try//必须使用Try catch,不然输入的字符串不是净荷明文程序就Gameover了  
            {
                var bytes = Convert.FromBase64String(securityTxt);
                var rsa = new RSACryptoServiceProvider(new CspParameters { KeyContainerName = "ccccccccccc" });

                var DecryptBytes = rsa.Decrypt(bytes, false);
                return Encoding.Default.GetString(DecryptBytes);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        #endregion


        #region 密匙向量加密
        //private byte[] keyvi= new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x07 };
      
        public static string DesEncrypt(string pToEncrypt)
        {
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);
                des.Key = ASCIIEncoding.ASCII.GetBytes(ApplicationEnvironments.Site.AESKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(ApplicationEnvironments.Site.AESIV);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Convert.ToBase64String(ms.ToArray());
                ms.Close();
                return str;
            }
            //var bytes = Encoding.Default.GetBytes(normalTxt);
            //var key = Encoding.UTF8.GetBytes(ConfigHelper.EncryptKey.PadLeft(8, '0').Substring(0, 8));
            //using (MemoryStream ms = new MemoryStream())
            //{
            //    var encry = new DESCryptoServiceProvider();
            //    CryptoStream cs = new CryptoStream(ms, encry.CreateEncryptor(key, keyvi), CryptoStreamMode.Write);
            //    cs.Write(bytes, 0, bytes.Length);
            //    cs.FlushFinalBlock();
            //    return Convert.ToBase64String(ms.ToArray());
            //}
        }
        public static string DesDecrypt(string pToDecrypt)//解密  
        {
            byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = ASCIIEncoding.ASCII.GetBytes(ApplicationEnvironments.Site.AESKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(ApplicationEnvironments.Site.AESIV);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                return str;
            }
            //try
            //{
            //    var bytes = Convert.FromBase64String(securityTxt);
            //    var key = Encoding.UTF8.GetBytes(ConfigHelper.EncryptKey.PadLeft(8, '0').Substring(0, 8));
            //    using (MemoryStream ms = new MemoryStream())
            //    {
            //        var descrypt = new DESCryptoServiceProvider();
            //        CryptoStream cs = new CryptoStream(ms, descrypt.CreateDecryptor(key, keyvi), CryptoStreamMode.Write);
            //        cs.Write(bytes, 0, bytes.Length);
            //        cs.FlushFinalBlock();
            //        return Encoding.UTF8.GetString(ms.ToArray());
            //    }

            //}
            //catch (Exception)
            //{
            //    return string.Empty;
            //}
        }
        #endregion

        #region SHA为不可逆加密方式  

        public static string SHA1Encrypt(string normalTxt)
        {
            var bytes = Encoding.Default.GetBytes(normalTxt);
            var SHA = new SHA1CryptoServiceProvider();
            var encryptbytes = SHA.ComputeHash(bytes);
            return Convert.ToBase64String(encryptbytes);
        }
        public static string SHA256Encrypt(string normalTxt)
        {
            var bytes = Encoding.Default.GetBytes(normalTxt);
            var SHA256 = new SHA256CryptoServiceProvider();
            var encryptbytes = SHA256.ComputeHash(bytes);
            return Convert.ToBase64String(encryptbytes);
        }
        public static string SHA384Encrypt(string normalTxt)
        {
            var bytes = Encoding.Default.GetBytes(normalTxt);
            var SHA384 = new SHA384CryptoServiceProvider();
            var encryptbytes = SHA384.ComputeHash(bytes);
            return Convert.ToBase64String(encryptbytes);
        }
        public static string SHA512Encrypt(string normalTxt)
        {
            var bytes = Encoding.Default.GetBytes(normalTxt);
            var SHA512 = new SHA512CryptoServiceProvider();
            var encryptbytes = SHA512.ComputeHash(bytes);
            return Convert.ToBase64String(encryptbytes);
        }
        #endregion

        #region AES

   
        private static string iv = "  ";
        public static string AESEncrypt(string text)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            rijndaelCipher.KeySize = 128;
            rijndaelCipher.BlockSize = 128;
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(ApplicationEnvironments.Site.AESKey);
            byte[] keyBytes = new byte[16];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length) len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);
            rijndaelCipher.IV = new byte[16];
            ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
            byte[] plainText = Encoding.UTF8.GetBytes(text);
            byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
            return Convert.ToBase64String(cipherBytes);
        }


        public static string AESDecrypt(string text)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            rijndaelCipher.KeySize = 128;
            rijndaelCipher.BlockSize = 128;
            byte[] encryptedData = Convert.FromBase64String(text);
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(ApplicationEnvironments.Site.AESKey);
            byte[] keyBytes = new byte[16];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length) len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);
            rijndaelCipher.IV = new byte[16];
            ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
            byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
            return Encoding.UTF8.GetString(plainText);
        }

        #endregion

        #region
        /// <summary>
        /// Md5二进制加密
        /// </summary>
        public static byte[] SHAEncrypt(string txt)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] hashBytes = encoding.GetBytes(txt);
            SHA1 sha1 = new SHA1CryptoServiceProvider();
            byte[] cryptPassword = sha1.ComputeHash(hashBytes);
            return cryptPassword;
        }
        #endregion
    }
}